/*
 * Copyright (c) 2025 [ByteDance Ltd. and/or its affiliates.] and/or its affiliates
 * SPDX-License-Identifier: LGPL v2.1+
*/
#ifndef ANDROID_FFmpegIOCryptor_H
#define ANDROID_FFmpegIOCryptor_H

#include "FFAny.h"
#include <map>

extern "C" {
#include <libavformat/avformat.h>
#include <libavutil/log.h>
}

enum TECryptorType {
    TECryptorType_None = 0,
    TECryptorType_XOR = 1,
};

extern const char *kTECryptorType;
// Params for xor cryptor
extern const char *kFFmpegIOCryptorParam_Step;    // uint32_t
extern const char *kFFmpegIOCryptorParam_Length;  // uint32_t
extern const char *kFFmpegIOCryptorParam_Key;     // uint8_t

class FFmpegIOCryptor {
public:
    virtual ~FFmpegIOCryptor() = default;

    /**
     * Return cryptor type
     * @return
     */
    virtual TECryptorType getType() const = 0;

    /**
     * Check if the cryptor is an encrytor
     * @return
     */
    virtual bool isEncryptor() const = 0;

    /**
     * Prepare for crypt
     * @param url
     * @param formatContext
     * @param options Options for open io
     * @param param Parameters for cryptor
     * @return 0 if success, otherwise return a negative error code
     */
    virtual int prepare(const char *url, AVFormatContext *formatContext, const AVDictionary *options, const std::map<std::string, FFAny> *params) = 0;

    /**
     * When AVFormatContext is invalid, clear it
     */
    virtual void clearFormatContext() = 0;
};

class FFmpegIOEncryptor : virtual public FFmpegIOCryptor {
public:
    virtual ~FFmpegIOEncryptor() override = default;

    /**
     * Write bytedance ve tag
     * @param writeParam
     * @return
     */
    virtual int writeBdveTag(bool writeParam) = 0;
};

/**
 * Create a decryptor
 * @param cryptorType
 * @return
 */
FFmpegIOCryptor *te_create_ffmpeg_io_decryptor(TECryptorType cryptorType);

/**
 * Create an encryptor
 * @param cryptorType
 * @return
 */
FFmpegIOEncryptor *te_create_ffmpeg_io_encryptor(TECryptorType cryptorType);

/**
 * Get cryptor type
 * @param url
 * @return
 */
TECryptorType te_get_cryptor_type(const char *url);

#endif   // ANDROID_FFmpegIOCryptor_H
